package t456

import (
	"errors"
	"strconv"
	"strings"
)

type MyStack struct {
	items []int
	//l     sync.Mutex
}

func (m *MyStack) Push(n int) {
	//m.l.Lock()
	//defer m.l.Unlock()
	m.items = append(m.items, n)
}

func (m *MyStack) Pop() (int, error) {
	//m.l.Lock()
	//defer m.l.Unlock()
	if len(m.items) == 0 {
		return 0, errors.New("empty of stack")
	}
	el := m.items[len(m.items)-1]
	m.items = m.items[:len(m.items)-1]
	return el, nil
}

func (m *MyStack) Top() (int, error) {
	//m.l.Lock()
	//defer m.l.Unlock()
	if len(m.items) == 0 {
		return 0, errors.New("empty of stack")
	}
	el := m.items[len(m.items)-1]
	return el, nil
}

func (m *MyStack) Size() int {
	return len(m.items)
}

func (m *MyStack) Empty() bool {
	if len(m.items) == 0 {
		return true
	}
	return false
}

func (m *MyStack) Clear() {
	m.items = m.items[0:0]
}

func (m *MyStack) String() string {
	tmp := make([]string, len(m.items))
	for _, item := range m.items {
		tmp = append(tmp, strconv.Itoa(item))
	}
	return strings.Join(tmp, " ")
}

func find132pattern(nums []int) bool {
	stack := &MyStack{}

	length := len(nums)

	head := 0

	for length-head >= 3 {
		k := head
		for k < length {
			num := nums[k]

			top, err := stack.Top()
			if err != nil {
				stack.Push(k)
				continue
			}
			//fmt.Println(top, num)
			size := stack.Size()
			if size == 1 {
				// 比较大小
				if nums[top] > num {
					// 当前比栈顶小
					_, _ = stack.Pop()
					stack.Push(k)
				} else if nums[top] < num {
					// 当前比栈顶大,且大过 1
					if num-nums[top] > 1 {
						stack.Push(k)
					}
				}
			} else if size == 2 {
				if nums[top] < num {
					_, _ = stack.Pop()
					stack.Push(k)
				} else if nums[top] > num {
					_, _ = stack.Pop()
					first, _ := stack.Top()
					if nums[first] < num {
						//fmt.Println(nums[first], nums[top], num)
						return true
					} else {
						stack.Push(top)
					}
				}
			}
			if k+1 == length {
				stack.Clear()
				head = top
			}
			k++
		}
		head++
	}

	return false
}
